package com.fly.base;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Data;
import org.dozer.DozerBeanMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.fly.base.DataTables.OrderStrategy.ASC;
import static com.fly.base.DataTables.OrderStrategy.DESC;

/**
 * Created by frinder6 on 2016/10/24.
 * <p>
 * 接收 dt前端框架参数
 * &
 * 返回服务器数据到前端 dt框架
 * <p>
 * 参考博文：http://blog.csdn.net/chenjing502/article/details/38285291
 */
@Data
public class DataTables<T> {

    private static final DozerBeanMapper MAPPER = new DozerBeanMapper();

    private static Logger logger = LoggerFactory.getLogger(DataTables.class);

    static {
        MAPPER.setMappingFiles(Collections.singletonList("dozer.xml"));
    }

    /**
     * 返回 T
     *
     * @param tClass
     * @return
     * @throws Exception
     */
    public T getObject(Class<T> tClass) throws Exception {
        T obj;
        if (null != target) {
            obj = MAPPER.map(target, tClass);
        } else {
            obj = tClass.newInstance();
        }
        return obj;
    }

    /**
     * 获取当前页
     *
     * @return
     */
    public int getPage() {
        return (start + length) / length;
    }


    /**
     * 获取排序列
     *
     * @return
     */
    public List<OrderBy> getOrderBys() {
        List<OrderBy> orderByList = Lists.newArrayList();
        if (null != order) {
            order.forEach(o -> {
                int index = o.get(Order.column) == null ? 0 : Integer.parseInt(o.get(Order.column).toString());
                int len = columns.size();
                if (index >= 0 && index <= (len - 1)) {
                    Object col = columns.get(index).get(Column.data);
                    if (null != col && !Strings.isNullOrEmpty(col.toString())) {
                        orderByList.add(
                                new OrderBy.Builder()
                                        .field(col.toString())
                                        .strategy("DESC".equalsIgnoreCase(o.get(Order.dir).toString()) ? DESC : ASC)
                                        .build()
                        );
                    }
                }
            });
        }
        if (orderByList.isEmpty()) {
            orderByList.add(new OrderBy.Builder().field("id").strategy(DESC).build());
        }
        return orderByList;
    }

    /**
     * 获取搜索文本
     *
     * @return
     */
    public String getSearchText() {
        return StringUtils.isEmpty(search) ? "" : search.get(Search.value);
    }

    /**
     * 请求&响应都需要属性
     */
    private int start = 0;

    private int length = 10;

    /**
     * 返回结果
     */
    private List<T> data;

    private long recordsTotal;

    private long recordsFiltered;

    /**
     * 请求参数
     */

    private long draw;

    private String pageNum;

    private List<Map<Column, Object>> columns;

    private List<Map<Order, Object>> order;

    private Map<Search, String> search;

    /**
     *
     */
    private Date createTimeFrom;

    private Date createTimeTo;

    /**
     * 快捷查询支持字段
     */
    private List<String> searchFields = Lists.newArrayList();

    private List<String> equalFields = Lists.newArrayList();

    private List<String> notEqualFields = Lists.newArrayList();

    private Map<String, List<Object>> inFields = Maps.newHashMap();

    private Map<String, List<Object>> notInFields = Maps.newHashMap();

    private Map<String, Integer> greaterThanFields = Maps.newHashMap();

    private Map<String, Integer> greaterThanOrEqualFields = Maps.newHashMap();

    private Map<String, Integer> lessThanFields = Maps.newHashMap();

    private Map<String, Integer> lessThanOrEqualFields = Maps.newHashMap();

    private List<Between> betweenList = Lists.newArrayList();

    /**
     * 接收查询参数
     */
    private Map<String, Object> target;


    public enum OrderStrategy {
        // 降序
        DESC,
        // 升序
        ASC
    }

    public static class OrderBy {
        private String field;
        private OrderStrategy strategy;

        public OrderBy() {
        }

        private OrderBy(Builder builder) {
            setField(builder.field);
            setStrategy(builder.strategy);
        }

        public String getField() {
            return field;
        }

        public void setField(String field) {
            this.field = field;
        }

        public OrderStrategy getStrategy() {
            return strategy;
        }

        public void setStrategy(OrderStrategy strategy) {
            this.strategy = strategy;
        }

        public static final class Builder {
            private String field;
            private OrderStrategy strategy;

            public Builder() {
            }

            public Builder field(String val) {
                field = val;
                return this;
            }

            public Builder strategy(OrderStrategy val) {
                strategy = val;
                return this;
            }

            public OrderBy build() {
                return new OrderBy(this);
            }
        }
    }

    /**
     * 表格右上侧搜索框
     */
    public enum Search {
        // 搜索字段
        value,
        // 搜索值
        regex
    }


    /**
     * 排序
     */
    public enum Order {
        // 字段
        column,
        // 策略
        dir
    }

    /**
     * 列
     */
    public enum Column {
        // 字段
        data,
        // 名称
        name,
        // 是否支持搜索
        searchable,
        // 是否支持排序
        orderable,
        // 搜索值
        searchValue,
        // 搜索~~
        searchRegex
    }

    @Data
    public static class Between {
        private String field;
        private Object minValue;
        private Object maxValue;
    }
}
